package com.geor.gcv.core.mat;

import org.opencv.core.Mat;
import org.slf4j.Logger;

import com.geor.common.log.Loggers;
import com.geor.gcv.core.model.Area;

public class SurroundArea {
	static Logger log = Loggers.get();
	private static SurroundArea sa;

	private SurroundArea() {

	}

	public static SurroundArea me() {
		synchronized (SurroundArea.class) {
			if (sa == null) {
				sa = new SurroundArea();
			}
			return sa;
		}
	}

	public synchronized Area excute(Mat mat, int num) {
		if (mat.channels() != 1) {
			log.error(getClass().getName() + " params mat must be single channel img !");
		}

		int startUp = getStartUp(mat, num);
		int endDown = getEndDown(mat, num);
		int startLeft = getStartLeft(mat, num);
		int endRight = getEndRight(mat, num);

		Area area = new Area(startLeft, startUp, endRight - startLeft, endDown - startUp);

		return area;
	}

	public synchronized Area excute(Mat mat) {
		return excute(mat, 1);
	}

	private int getStartUp(Mat bin, int index) {
		int startUp = 0;
		for (int row = 0; row < bin.rows(); row++) {
			int num = 0;
			for (int col = 0; col < bin.cols(); col++) {
				int pex = (int) bin.get(row, col)[0];
				// 白色
				if (pex > 100) {
					num++;
				}
				if (num > index) {
					startUp = row;
					break;
				}
			}
			if (num > index) {
				break;
			}
		}
		return startUp;
	}

	private int getEndDown(Mat bin, int index) {
		int endDown = 0;
		for (int row = bin.rows() - 1; row >= 0; row--) {
			int num = 0;
			for (int col = 0; col < bin.cols(); col++) {
				int pex = (int) bin.get(row, col)[0];
				if (pex > 100) {
					num++;
				}
				if (num > index) {
					endDown = row;
					break;
				}
			}
			if (num > index) {
				break;
			}
		}
		return endDown + 1;
	}

	private int getStartLeft(Mat bin, int index) {
		int startLeft = 0;

		for (int col = 0; col < bin.cols(); col++) {
			int num = 0;
			for (int row = 0; row < bin.rows(); row++) {
				int pex = (int) bin.get(row, col)[0];
				if (pex > 100) {
					num++;
				}
				if (num > index) {
					startLeft = col;
					break;
				}
			}
			if (num > index) {
				break;
			}
		}

		return startLeft;
	}

	private int getEndRight(Mat bin, int index) {
		int endRight = 0;
		for (int col = bin.cols() - 1; col >= 0; col--) {
			int num = 0;
			for (int row = 0; row < bin.rows(); row++) {
				int pex = (int) bin.get(row, col)[0];
				if (pex > 100) {
					num++;
				}
				if (num > index) {
					endRight = col;
					break;
				}
			}
			if (num > index) {
				break;
			}
		}
		return endRight + 1;
	}

}
